package main

import (
	"errors"
	"fmt"
	"sync"
	"time"
)
import (
	"Ghost/cmd"
	"Ghost/mss"
	"Ghost/ntk"
	. "Ghost/utd"
	"GhostTool/TestSvr/pack"
)

const (
	SID_TEST_BEGIN = mss.DEF_SERVICE_START_ID + iota
	SID_CONSOLE_INPUT
	SID_TEST_SERVER
)

func init() {
	mss.SetSeiName(SID_CONSOLE_INPUT, "SID_CONSOLE_INPUT")
	mss.SetSeiName(SID_TEST_SERVER, "SID_TEST_SERVER")
}

func main() {
	// - 初始化你的控制台参数 系统信号
	USys.Init(&SLogSetting{Level: ELL_Trace})
	ntk.EnableDebug(true)

	// - 至少要注册控制台服务
	mss.Regist(SID_TEST_SERVER, &TestServer{})
	mss.Regist(SID_CONSOLE_INPUT, &cmd.CommandLine{})
	// - 所有刚注册的服务运行
	mss.Work()

	// - 等待系统结束
	USys.Wait()
}

type TestServer struct {
	ntk.TcpServer

	mapUnClients map[ntk.TConnId]ntk.IClienter // 未认证的客户端
}

//------------------------------------------------------------------------------
//================================服务处理方法==================================
//------------------------------------------------------------------------------
func (this *TestServer) HandleInit(own mss.IOServicer) {
	this.TcpServer.HandleInit(own)

	this.mapUnClients = make(map[ntk.TConnId]ntk.IClienter, 2)
	this.SetListenPort(11111)
	this.SetClientCapy(1000)
	this.SetClientsMax(10000)
	this.SetMsgHandMode(ntk.EMHM_Multi) // 并发模式
}
func (this *TestServer) HandleRate() int { return 30 }
func (this *TestServer) HandleCapy() int { return 100 }
func (this *TestServer) HandleStart() error {
	this.SetMsgHandle(pack.MT_SERVER_PING, this.OnMsgServerPing)
	this.SetMsgHandle(pack.MT_HAND_SHAKE_Q, this.OnMsgHandShakeQ)
	return this.TcpServer.HandleStart()
}
func (this *TestServer) HandleTick() {
	this.tickUnClient()
}
func (this *TestServer) HandleAccepted(client ntk.IClienter) {
	this.addUnClient(client)
}
func (this *TestServer) HandleDisConnect(client ntk.IClienter, remain []ntk.IMsger, reason error) {
	this.delUnClient(client)
	this.onClientDisConnect(client, reason)
}

//------------------------------------------------------------------------------
//===============================逻辑处理方法===================================
//------------------------------------------------------------------------------

func (this *TestServer) tickUnClient() {
	authtime := time.Second * 30
	for id, client := range this.mapUnClients {
		if time.Since(client.TimeStart()) < authtime { //短时间内必须验证
			continue
		}
		this.CloseClient(client, errors.New(fmt.Sprintf("client[%d] not auth in auth_time[%v]", id, authtime)))
	}
}
func (this *TestServer) delUnClient(client ntk.IClienter) {
	this.muClients.Lock()
	delete(this.mapUnClients, client.ConnectId())
	this.muClients.Unlock()
}
func (this *TestServer) addUnClient(client ntk.IClienter) {
	this.muClients.Lock()
	this.mapUnClients[client.ConnectId()] = client
	this.muClients.Unlock()
}

func (this *TestServer) onClientDisConnect(client ntk.IClienter, reason error) {
	ULog.Warnf("Client[%d] DisConnected. reason:%q", client.ConnectId(), reason)
}

//------------------------------------------------------------------------------
//================================消息处理方法====================================
//------------------------------------------------------------------------------
func (this *TestServer) OnMsgServerPing(client ntk.IClienter, msg ntk.IMsger) error {
	// if client.GetUserData() == nil {
	// 	return nil
	// }
	// client.GetUserData().(*MasterPeer).setLastPingTime(time.Now())
	return client.SendMsg(msg)
}
func (this *TestServer) OnMsgHandShakeQ(client ntk.IClienter, msg ntk.IMsger) error {
	req, ack := msg.(*pack.MsgHandShakeQ), pack.MakeMsgHandShakeA()
	ntk.TinkerRespond(req, ack)
	nServerId, nServerType := req.CliInfo.ServerId, (req.CliInfo.ServerType)

	if !(nServerType == 100) {
		return ntk.SendNetErrRet(client, ack, pack.EHandShakeAParams)
	}
	if req.ShakKey != "DEF_SERVER_KEY" {
		return ntk.SendNetErrRet(client, ack, pack.EHandShakeAShakeKey)
	}

	this.delUnClient(client)

	ULog.Infof("MasterPeer[%s ServerId[%d]] Regist to me OK.", req.CliName, nServerId)
	ack.DRet = &pack.MsgHandShakeA_Data{ServerInfo: req.CliInfo, ServerName: req.CliName}
	return client.SendMsg(ack)
}
